package Controller

import (
	"computer_set/global"
	"computer_set/model"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"sync"
	"time"
)

// 身体部位药材结构体
type BodyPartHerbs struct {
	BodyPart string              `json:"body_part"`
	Count    int                 `json:"count"`
	Herbs    []model.BookContext `json:"herbs"`
}

// 新增爬虫函数获取药材详细信息
func crawlHerbEffects(herbName string) (string, error) {
	client := &http.Client{Timeout: 10 * time.Second}

	// 使用百度健康作为数据源
	url := fmt.Sprintf("https://health.baidu.com/api/search?word=%s", url.QueryEscape(herbName+"功效"))
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...")

	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return "", fmt.Errorf("HTTP %d", resp.StatusCode)
	}

	// 解析JSON响应
	var result struct {
		Data struct {
			Disease []struct {
				Content string `json:"content"`
			} `json:"disease"`
		} `json:"data"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return "", fmt.Errorf("解析失败: %v", err)
	}

	if len(result.Data.Disease) == 0 {
		return "", fmt.Errorf("未找到相关信息")
	}

	return result.Data.Disease[0].Content, nil
}

func GetBodyPartHerbs(c *gin.Context) {
	// 从数据库获取所有药材
	var herbs []model.BookContext
	db := global.DB
	if err := db.Select("id, herb_name, efficacy, description").
		Where("efficacy IS NOT NULL OR description IS NOT NULL").
		Limit(1000).
		Find(&herbs).Error; err != nil {
	}

	// 定义身体部位映射关系
	bodyParts := map[string][]string{
		"liver":           {"肝", "肝胆", "疏肝", "养肝"},
		"lung":            {"肺", "润肺", "清肺", "止咳"},
		"kidney":          {"肾", "补肾", "益肾", "固精"},
		"spleen":          {"脾", "健脾", "补脾", "脾胃"},
		"small-intestine": {"小肠", "肠燥", "肠痈", "补益"},
		"large-intestine": {"大肠", "润肠", "通便", "便秘"},
		"heart":           {"心", "养心", "清心", "安神"},
	}

	// 初始化结果集
	result := make(map[string]*BodyPartHerbs)
	for part := range bodyParts {
		result[part] = &BodyPartHerbs{
			BodyPart: part,
			Herbs:    make([]model.BookContext, 0),
		}
	}

	// 使用工作池控制并发
	var wg sync.WaitGroup
	herbChan := make(chan model.BookContext, 100)
	resultChan := make(chan model.BookContext, 100)

	// 启动5个爬虫worker
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for herb := range herbChan {
				// 优先使用数据库已有信息
				content := herb.Description + "\n" + herb.Efficacy

				// 如果信息不足则爬取网络数据
				if len(content) < 100 {
					if detail, err := crawlHerbEffects(herb.HerbName); err == nil {
						herb.Description += "\n网络数据：" + detail
					}
				}
				resultChan <- herb
			}
		}()
	}

	// 发送任务
	go func() {
		for i := range herbs {
			herbChan <- herbs[i]
		}
		close(herbChan)
	}()

	// 处理结果
	go func() {
		wg.Wait()
		close(resultChan)
	}()

	// 匹配身体部位
	for herb := range resultChan {
		content := strings.ToLower(herb.Description + herb.Efficacy)

	MATCH_LOOP:
		for part, keywords := range bodyParts {
			for _, kw := range keywords {
				if strings.Contains(content, kw) {
					result[part].Herbs = append(result[part].Herbs, herb)
					result[part].Count++
					break MATCH_LOOP // 匹配到即跳出
				}
			}
		}
	}

	// 转换最终结果
	finalResult := make([]BodyPartHerbs, 0)
	for _, part := range []string{"liver", "lung", "kidney", "spleen",
		"small-intestine", "large-intestine", "heart"} {
		data := result[part]
		// 按药材名称排序
		sort.Slice(data.Herbs, func(i, j int) bool {
			return data.Herbs[i].HerbName < data.Herbs[j].HerbName
		})
		finalResult = append(finalResult, *data)
	}

	c.JSON(200, finalResult)
}
